//------------------------------------------------------------------------------
// $Id:  $
// $HeadURL:  $
//
// Classification: UNCLASSIFIED
//
// Copyright (c) JTrustN
// All rights reserved
// @author ${user}
//------------------------------------------------------------------------------
package vlcjdemo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class FFprobeParser {

//    public static final int MAX_PROCES_WAIT_TIME = 10 * 60 * 1000;
    ArrayList<MovieClip> aMovieList = new ArrayList<MovieClip>();
    ArrayList<MovieClip> aMovieOutList = new ArrayList<MovieClip>();
    ArrayList<MovieClip> aOptimizedMovieList = new ArrayList<MovieClip>();
    int width = 0;
    int height = 0;
    float frames = 0.0f;
    int cropWidth = 0;
    int cropHeight = 0;
    public final static long thumbNailWidth = 200;
    long thumbNailHeight = 120;
    float aspect = -1.0f;
    boolean debug = false;
    DateFormat formatter = new SimpleDateFormat("H:mm:ss.SSS");
    boolean baselineProfile = true;
    boolean sharpen = false;
    boolean licence = true;
    String movieName = "";
    MovDB aMovDB;

    FFprobeParser() {
        formatter.setTimeZone(java.util.TimeZone.getTimeZone("Zulu"));
    }

    public void deleteFile(String lmovieName) {
        if (lmovieName != null && lmovieName.length() > 0) {
            try {
                File f = new File(lmovieName);
                f.delete();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    public void writePlayCmd(MovieClip aMovieClip) {
        System.out.println("writePlayCmd");
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter("play.cmd"));
            writer.write("ffplay.exe -window_title \"" + aMovieClip.parrent.movieName + " T:" + aMovieClip.time + "\"");
//            if (aMovieClip.duration.length() > 0) {
//                writer.write(" -ss " + aMovieClip.time + " -t " + aMovieClip.duration);
//            } else {
            writer.write(" -ss " + aMovieClip.time);
//            }
            writer.write(" -framedrop -loop 0 -i \"" + aMovieClip.parrent.movieName + "\"");
            writer.newLine();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        getCmdResult("play.cmd");
    }

    public void writePlayMovieCmd() {
        System.out.println("writePlayMovieCmd");
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter("playMovie.cmd"));
            writer.write("ffplay.exe -window_title \"" + movieName + "\"");
            writer.write(" -framedrop -loop 0 -i \"" + movieName + "\"");
            writer.newLine();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        getCmdResult("playMovie.cmd");
    }

    public void writeAppendCmd(String outMovieName) {
        System.out.println("writeAppendCmd, outMovieName = " + outMovieName);
        long cnt = 1000;
        movieName = outMovieName;
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter("append.cmd"));
            writer.write("MP4Box.exe ");
            String cat = " -add ";
            MovieClip[] times = aOptimizedMovieList.toArray(new MovieClip[0]);
            for (MovieClip aMovieClip : times) {
                writer.write(cat);
                writer.write("movieOut" + cnt + ".mp4 ");
                cat = " -cat ";
                cnt++;
            }
            writer.write("-keep-all -hint -itags tool=\"mp4FilmMaker test\" -new \"" + outMovieName + "\"");
            writer.newLine();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        getCmdResult("append.cmd");
    }

    public void writeFFMpegCmd(boolean size, int lwidth, int lheight, boolean audioHzSelected, int audioHz,
        boolean avi, int clipcount) {
        System.out.println("writeFFMpegCmd");

        if (aMovieOutList.size() > 0) {
            MovieClip[] inclips = aMovieOutList.toArray(new MovieClip[0]);
            MovieClip prevClip = null;
            aOptimizedMovieList.clear();

            for (MovieClip aMovieClip : inclips) {
                if (prevClip != null) {
                    if (aMovieClip == prevClip.nextClip) {
                        if (aMovieClip.nextClip != null) {
                            prevClip.durationDateL = prevClip.durationDateL + aMovieClip.durationDateL;
                        } else {
                            prevClip.duration = "";
                        }
                        prevClip.nextClip = aMovieClip.nextClip;
                    } else {
                        if (prevClip.duration.length() > 0) {
                            Date time = new Date(prevClip.durationDateL);
                            String timeStr = formatter.format(time);
                            prevClip.duration = timeStr;
                        }
                        prevClip = aMovieClip.copy();
                        aOptimizedMovieList.add(prevClip);
                    }
                } else {
                    prevClip = aMovieClip.copy();
                    aOptimizedMovieList.add(prevClip);
                }
            }
            if (prevClip.duration.length() > 0) {
                Date time = new Date(prevClip.durationDateL);
                String timeStr = formatter.format(time);
                prevClip.duration = timeStr;
            }

            BufferedWriter writer = null;
            try {
                writer = new BufferedWriter(new FileWriter("ffmpeg.cmd"));
                long cnt = 1000;
                MovieClip[] clips = aOptimizedMovieList.toArray(new MovieClip[0]);
                for (MovieClip aMovieClip : clips) {
                    if (size) {
                        width = lwidth;
                        height = lheight;
                        frames = 25;
                        double ratio = 1.0 * aMovieClip.parrent.height / height;
                        long lcropWidth = Math.round((aMovieClip.parrent.width / ratio - width) * 0.5);
                        if (lcropWidth > 0) {
                            cropWidth = (int) lcropWidth;
                            width = (int) (width + 2 * cropWidth);
                            aspect = 1.0f * lwidth / height;
                        } else {
                            width = (int) (lwidth + 2 * lcropWidth);
                            aspect = 1.0f * width / height;
                        }
                    } else {
                        width = 0;
                        height = 0;
                    }
                    writer.write("start /b /low /wait ffmpeg.exe -y -ss ");
                    writer.write(aMovieClip.time);
                    writer.write(" -i \"");
                    writer.write(aMovieClip.parrent.movieName);

                    if (!avi) { // MP4
                        writer.write("\" -vcodec libx264 -preset slow -tune film");
                        if (baselineProfile) {
                            writer.write(" -profile baseline");
                        } else {
                            writer.write(" ");
                        }
                        writer.write(" -crf 21 -threads 0");
                        if (width > 0 && height > 0) {
                            writer.write(" -s " + width + "x" + height);
                        }
                        if (aspect > 0) {
                            writer.write(" -aspect " + aspect);
                        }
                        if (cropWidth > 0 || cropHeight > 0) {
                            writer.write(" -vf crop=in_w-2*" + cropWidth + ":in_h-2*" + cropHeight);
                        }
                        if (sharpen) {
                            writer.write(" -vf unsharp=7:7:5.0:7:7:5.0");
                        }
                        if (!licence) {
                            writer.write(" -vf drawtext=\"fontfile=./vrinda.ttf: text='mp4FilmMaker': x=1: y=1: fontsize=12: fontcolor=black@0.5: box=1: boxcolor=gray@0.2\"");
                        }

                        if (frames > 0.0) {
                            writer.write(" -r " + frames);
                        }
                        writer.write(" -metadata title=\"mp4FilmMaker test\" -metadata author=\"mp4FilmMaker\" -vol 100");

                        if (audioHzSelected) {
                            if (audioHz < 1000) {
                                writer.write(" -an ");
                            } else {
                                writer.write(" -ar " + audioHz);
                            }
                        }

                        if (aMovieClip.duration.length() > 0) {
                            writer.write(" -t " + aMovieClip.duration);
                        }
                        writer.write(" -async 1 -f mp4 \"movieOut" + cnt + ".mp4\" ");

                    } else {  // AVI
                        writer.write("\" ");
                        if (aMovieClip.duration.length() > 0) {
                            writer.write(" -t " + aMovieClip.duration);
                        }
                        if (aMovieClip.parrent.aspect > 0.0) {
                            writer.write(" -aspect " + aMovieClip.parrent.aspect);
                        }
                        movieName = aMovieClip.parrent.movieName + clipcount + "_" + cnt + ".avi";
                        writer.write(" -sameq -async 1 -f avi \"" + movieName + "\" ");
                    }

                    writer.newLine();
                    cnt++;
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    if (writer != null) {
                        writer.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            getCmdResult("ffmpeg.cmd");
        }
    }

    public void writeFFProbeCmd(String lmovieName) {
        System.out.println("writeFFProbeCmd, movieName= " + movieName);
        movieName = lmovieName;
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter("ffprobe.cmd"));
            writer.write("ffprobe.exe -pretty -show_format -show_streams -show_packets \"");
            writer.write(movieName);
            writer.write("\" > out-probe.txt");
            writer.newLine();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        getCmdResult("ffprobe.cmd");
        parse("out-probe.txt");
    }

    public void writeJpgCmd() {
        System.out.println("writeJpgCmd, movieName= " + movieName);
        BufferedWriter writer = null;
        if (width > 0 && height > 0) {
            try {
                double ratio = 1.0 * width / thumbNailWidth;
                thumbNailHeight = Math.round(height / ratio);
                writer = new BufferedWriter(new FileWriter("jpg.cmd"));
                long cnt = 1000;
                MovieClip[] times = aMovieList.toArray(new MovieClip[0]);
                for (MovieClip aMovieClip : times) {
                    writer.write("ffmpeg.exe  -y -ss ");

                    if (aMovieClip.duration.length() > 0) {
                        Date time = new Date(aMovieClip.timeDateL + aMovieClip.durationDateL / 2);
                        String timeStr = formatter.format(time);
                        writer.write(timeStr);
                    } else {
                        writer.write(aMovieClip.time);
                    }

//                    writer.write(aMovieClip.time);
                    writer.write(" -i \"");
                    writer.write(movieName);
                    writer.write("\" -vcodec mjpeg -vframes 1 -an -f rawvideo -s " + thumbNailWidth + "x" + thumbNailHeight);
                    writer.write(" out" + cnt + ".jpg");
                    writer.newLine();
                    aMovieClip.jpgName = "out" + cnt + ".jpg";
                    cnt++;
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    if (writer != null) {
                        writer.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        getCmdResult("jpg.cmd");
    }

    public void parse(String fileName) {
        System.out.println("parse, fileName= " + fileName + ", movieName= " + movieName);
        File file = new File(fileName);
        BufferedReader reader = null;
        String Start = "[";
        String End = "[/";
        String Packet = "[PACKET]";
        String Stream = "[STREAM]";
        String CodecType = "codec_type=video";
        String FlagsK = "flags=K";
        String Time = "dts_time=";
        String Width = "width=";
        String Height = "height=";
        String FrameRate = "r_frame_rate=";
        String Aspect = "display_aspect_ratio=";
        boolean insidePacket = false;
        boolean insideStream = false;
        boolean video = false;
        boolean flags = false;
        String time = "";
        int lwidth = 0;
        int lheight = 0;
        String lframes = "";
        String laspect = "";
        Date prevdate = null;
        try {
            prevdate = (Date) formatter.parse("0:00:00.000");
        } catch (ParseException ex) {
            ex.printStackTrace();
        }
        MovieClip aMovieClip = null;

        try {
            reader = new BufferedReader(new FileReader(file));
            String text = null;

// repeat until all lines is read
            while ((text = reader.readLine()) != null) {
                if (text.startsWith(End)) {
                    if (insidePacket) {
                        if (flags && video && time.length() > 0 && !time.equalsIgnoreCase("n/a")) {
                            Date date = null;
                            String time2 = "";
                            try {
                                time2 = time.substring(0, 11);
                                date = (Date) formatter.parse(time2);
                            } catch (Exception ex) {
                                ex.printStackTrace();
                            }
                            MovieClip tempClip = new MovieClip();
                            tempClip.parrent = this;
                            if (aMovieClip != null) {
                                aMovieClip.nextClip = tempClip;
                                long delta = date.getTime() - prevdate.getTime();
                                Date durationDate = new Date(delta);
                                aMovieClip.durationDateL = durationDate.getTime();
                                String durationStr = formatter.format(durationDate);
                                prevdate = date;
                                aMovieClip.duration = durationStr;
                            }
                            aMovieClip = tempClip;
                            aMovieClip.time = time2;
                            aMovieClip.timeDateL = date.getTime();
//                            aMovieClip.movieName = movieName;
                            aMovieList.add(aMovieClip);
                        }
                    }
                    if (insideStream) {
                        if (video && lwidth > 0) {
                            width = lwidth;
                        }
                        if (video && lheight > 0) {
                            height = lheight;
                        }
                        if (video && lframes.length() > 0) {
                            try {
                                int idx = lframes.indexOf('/');
                                String number = lframes;
                                if (idx > 0) {
                                    number = lframes.substring(0, idx);
                                    String number2 = lframes.substring(idx + 1);
                                    int frames1 = Integer.parseInt(number);
                                    int frames2 = Integer.parseInt(number2);
                                    frames = 1.0f * frames1 / frames2;
                                } else {
                                    frames = Integer.parseInt(number);
                                }
                            } catch (NumberFormatException numberFormatException) {
                                numberFormatException.printStackTrace();
                            }
                        }
                        if (video && laspect.length() > 0) {
                            try {
                                int idx = laspect.indexOf(':');
                                if (idx > 0) {
                                    String number = laspect.substring(0, idx);
                                    String number2 = laspect.substring(idx + 1);
                                    int aspect1 = Integer.parseInt(number);
                                    int aspect2 = Integer.parseInt(number2);
                                    aspect = 1.0f * aspect1 / aspect2;
                                }
                            } catch (NumberFormatException numberFormatException) {
                                numberFormatException.printStackTrace();
                            }
                        }

                    }

                    insidePacket = false;
                    insideStream = false;
                    flags = false;
                    video = false;
                    time = "";
                    lframes = "";
                    laspect = "";
                } else if (text.startsWith(Start)) {
                    if (text.startsWith(Packet)) {
                        insidePacket = true;
                    }
                    if (text.startsWith(Stream)) {
                        insideStream = true;
                    }
                } else {
                    if (insidePacket) {
                        if (text.startsWith(CodecType)) {
                            video = true;
                        }
                        if (text.startsWith(FlagsK)) {
                            flags = true;
                        }
                        if (text.startsWith(Time)) {
                            time = text.substring(Time.length());
                        }
                    }
                    if (insideStream) {
                        if (text.startsWith(CodecType)) {
                            video = true;
                        }
                        if (text.startsWith(Width)) {
                            try {
                                lwidth = Integer.parseInt(text.substring(Width.length()));
                            } catch (NumberFormatException numberFormatException) {
                                numberFormatException.printStackTrace();
                            }
                        }
                        if (text.startsWith(Height)) {
                            try {
                                lheight = Integer.parseInt(text.substring(Height.length()));
                            } catch (NumberFormatException numberFormatException) {
                                numberFormatException.printStackTrace();
                            }
                        }
                        if (text.startsWith(FrameRate)) {
                            lframes = text.substring(FrameRate.length());
                        }
                        if (text.startsWith(Aspect)) {
                            laspect = text.substring(Aspect.length());
                        }
                    }
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (aspect > 0.0) {
            width = Math.round(height * aspect);
        }
        System.out.println("Width = " + width);
        System.out.println("Height = " + height);
        System.out.println("Frames = " + frames);
        if (debug) {
            MovieClip[] times = aMovieList.toArray(new MovieClip[0]);
            for (MovieClip string : times) {
                System.out.println(string.time + ", " + string.duration);
            }
        }
    }

    public void writeFFProbeCmdMov(String lmovieName, Mov mov) {
        System.out.println("writeFFProbeCmdMov, movieName= " + movieName);
        movieName = lmovieName;
        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter("ffprobe.cmd"));
            writer.write("ffprobe.exe -pretty -show_format -show_streams \"");
            writer.write(movieName);
            writer.write("\" > out-probe.txt");
            writer.newLine();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        getCmdResult("ffprobe.cmd");
        parseMov("out-probe.txt", mov);
    }

    public void parseMov(String fileName, Mov mov) {
        System.out.println("parseMov, fileName= " + fileName + ", movieName= " + movieName);
        File file = new File(fileName);
        BufferedReader reader = null;
        PropertiesExt videoProps = null;
        PropertiesExt audioProps = null;
        PropertiesExt formatProps = null;
        String Stream = "[STREAM]";
        String StreamEnd = "[/STREAM]";
        boolean insideStream = false;
        String Format = "[FORMAT]";
        String FormatEnd = "[/FORMAT]";
        boolean insideFormat = false;

        try {
            reader = new BufferedReader(new FileReader(file));
            String text = null;
            PropertiesExt props = null;

            while ((text = reader.readLine()) != null) {
                try {
                    text = text.trim();

                    if (text.startsWith(Stream)) {
                        insideStream = true;
                        props = new PropertiesExt();
                    } else if (text.startsWith(StreamEnd)) {
                        insideStream = false;
                        String type = props.getProperty("codec_type");
                        if (type != null && type.equalsIgnoreCase("video")) {
                            videoProps = props;
                        }
                        if (type != null && type.equalsIgnoreCase("audio")) {
                            audioProps = props;
                        }
                    } else if (insideStream) {
                        props.add(text);
                    }

                    if (text.startsWith(Format)) {
                        insideFormat = true;
                        props = new PropertiesExt();
                    } else if (text.startsWith(FormatEnd)) {
                        insideFormat = false;
                        formatProps = props;
                    } else if (insideFormat) {
                        props.add(text);
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (formatProps != null) {
            String duration = formatProps.getProperty("duration");
            try {
                String time2 = duration.substring(0, 11);
                Date date = (Date) formatter.parse(time2);
                mov.info.put("duration", date);
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            String start_time = formatProps.getProperty("start_time");
            Date sdate = new Date(0);
            try {
                String time2 = start_time.substring(0, 11);
                sdate = (Date) formatter.parse(time2);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            mov.info.put("starttime", sdate);

            String format_name = formatProps.getProperty("format_name");
            mov.info.put("fileformat", format_name);

            String bit_rate = formatProps.getProperty("bit_rate");
            mov.info.put("bitrate", bit_rate);
        }

        if (videoProps != null) {
            String codec_name = videoProps.getProperty("codec_name");
            mov.info.put("videocodec", codec_name);

            String width = videoProps.getProperty("width");
            Long w = new Long(width);
            mov.info.put("width", w);

            String height = videoProps.getProperty("height");
            Long h = new Long(height);
            mov.info.put("height", h);
        }

        if (audioProps != null) {
            String codec_name = audioProps.getProperty("codec_name");
            mov.info.put("audiocodec", codec_name);

            String sample_rate = audioProps.getProperty("sample_rate");
            mov.info.put("audiosamplerate", sample_rate);

        }

        if (debug) {
        }
    }

    public void writeJpgCmdMov(String movieName, Mov mov) {
        System.out.println("writeJpgCmdMov, movieName= " + movieName);
        width = ((Long) mov.info.get("width")).intValue();
        height = ((Long) mov.info.get("height")).intValue();
        String jpgname = "MovDB_" + (Long) mov.info.get("Checksum") + ".jpg";
        Date duration = (Date) mov.info.get("duration");
        Date starttime = (Date) mov.info.get("starttime");

        BufferedWriter writer = null;
        if (width > 0 && height > 0) {
            try {
                double ratio = 1.0 * width / thumbNailWidth;
                thumbNailHeight = Math.round(height / ratio);
                writer = new BufferedWriter(new FileWriter("jpg.cmd"));
                writer.write("ffmpeg.exe  -y -ss ");

                if (duration.getTime() > 30000) {
                    Date time = new Date(starttime.getTime() + 20000);
                    String timeStr = formatter.format(time);
                    writer.write(timeStr);
                } else {
                    Date time = new Date(starttime.getTime() + (duration.getTime() / 2));
                    String timeStr = formatter.format(time);
                    writer.write(timeStr);
                }
                writer.write(" -i \"");
                writer.write(movieName);
                writer.write("\" -vcodec mjpeg -qscale 9 -vframes 1 -an -f rawvideo -s " + thumbNailWidth + "x" + thumbNailHeight);
                writer.write(" " + aMovDB.curDir + "img" + File.separator + jpgname);
                writer.newLine();
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    if (writer != null) {
                        writer.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        getCmdResult("jpg.cmd");
    }

    private void printList(String type, List l) {
        Iterator iter = l.iterator();
        while (iter.hasNext()) {
            String item = (String) iter.next();
            System.out.println(type + item);
        }
    }

    private List getCmdResult(String command) {
        System.out.println("getCmdResult, command= " + command);
        List res = new ArrayList();
        List err = new ArrayList();
        try {
            Process child = Runtime.getRuntime().exec(command);
            StreamGobbler errorGobbler = new StreamGobbler(child.getErrorStream(), err);

            StreamGobbler outputGobbler = new StreamGobbler(child.getInputStream(), res);

            // kick them off
            errorGobbler.setName("errordeamonpwd");
            errorGobbler.start();
            outputGobbler.setName("outputdeamonpwd");
            outputGobbler.start();

//            try {
//                Thread.currentThread().sleep(100);
//            } catch (InterruptedException ex) {
//                ex.printStackTrace();
//            }

            // any error???
            int exitVal = child.waitFor();
            errorGobbler.join();
            outputGobbler.join();
            if (debug) {
                System.out.println("Cmd: " + command);
                printList("stdOut: ", res);
                printList("stdErr: ", err);
            }
        } catch (Exception ex) {
            System.out.println("Error: " + ex);
        }
        return res;
    }

    private class StreamGobbler
        extends Thread {

        InputStream is;
        List res;

        StreamGobbler(InputStream is, List lres) {
            this.is = is;
            this.res = lres;
            setDaemon(true);
        }

        public void run() {
            try {
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                while ((line = br.readLine()) != null) {
                    if (debug) {
                        res.add(line);
                    }
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }
}
